package edu.nf.relaxenjoy.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;
import edu.nf.relaxenjoy.common.constant.platform.PlatformConstant;
import edu.nf.relaxenjoy.common.util.ConvertUtils;
import edu.nf.relaxenjoy.common.util.JsonUtils;
import edu.nf.relaxenjoy.common.util.PageUtils;
import edu.nf.relaxenjoy.common.util.RedisUtils;
import edu.nf.relaxenjoy.domain.dto.SearchRecordDTO;
import edu.nf.relaxenjoy.domain.entity.*;
import edu.nf.relaxenjoy.domain.vo.FollowVo;
import edu.nf.relaxenjoy.domain.vo.TrendVo;
import edu.nf.relaxenjoy.domain.vo.UserRecordVo;
import edu.nf.relaxenjoy.domain.vo.UserVo;
import edu.nf.relaxenjoy.mapper.*;
import edu.nf.relaxenjoy.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author zhu
 * @date 2024-12-16
 */
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {

    private final UserMapper userMapper;

    private final FollowMapper followMapper;

    private final AlbumMapper albumMapper;

    private final AlbumRelationMapper albumRelationMapper;

    private final RedisUtils redisUtils;

    private final PostMapper postMapper;

    @Override
    public void addBulkUserRecord() {
        List<User> list = userMapper.getList();
        for (User user : list) {
            String userRecordKey = PlatformConstant.USER_RECORD + user.getId();
            UserRecordVo userRecordVo = new UserRecordVo();
            userRecordVo.setUid(user.getId());
            userRecordVo.setAgreeCollectionCount(0L);
            userRecordVo.setAddFollowCount(0L);
            userRecordVo.setNoreplyCount(0L);
            redisUtils.set(userRecordKey, JsonUtils.toJsonString(userRecordVo));
        }
    }

    @Override
    public PageInfo<TrendVo> getTrendByUser(long page, long limit, Long userId, Integer type) {
        PageInfo<Post> postPage;
        if (type == 0) {
            postPage = new PageInfo<>(postMapper.getListByUid(userId, 0));
        } else {
            postPage = new PageInfo<>(postMapper.getListByUid(userId, null));
        }

        List<TrendVo> trendVoList = new ArrayList<>();
        List<Post> postList = postPage.getList();
        long total = postPage.getTotal();

        List<Long> mids = postList.stream().map(Post::getId).collect(Collectors.toList());
        List<AlbumRelation> albumRelationList = albumRelationMapper.getListByMids(mids);
        List<Long> aids = albumRelationList.stream().map(AlbumRelation::getAid).collect(Collectors.toList());
        Map<Long, AlbumRelation> albumRelationMap = new HashMap<>();
        List<Album> albumList = albumMapper.listByIds(aids);
        Map<Long, Album> albumMap = new HashMap<>();
        albumRelationList.forEach(item -> {
            albumRelationMap.put(item.getMid(), item);
        });
        albumList.forEach(item -> {
            albumMap.put(item.getId(), item);
        });

        TrendVo trendVo;
        for (Post model : postList) {
            AlbumRelation albumRelation = albumRelationMap.get(model.getId());
            trendVo = ConvertUtils.sourceToTarget(model, TrendVo.class);
            trendVo.setMid(model.getId())
                    .setStatus(model.getStatus())
                    .setTime(model.getUpdateDate())
                    .setImgsUrl(model.getImages().replace("\\\"", "\""));
            if (albumRelation != null) {
                Album album = albumMap.get(albumRelation.getAid());
                trendVo.setAlbumId(album.getId())
                        .setAlbumName(album.getName());
            }
            trendVoList.add(trendVo);
        }

        PageInfo<TrendVo> trendVoPage = new PageInfo<>();
        trendVoPage.setPageNum(postPage.getPageNum());
        trendVoPage.setPageSize(postPage.getPageSize());
        trendVoPage.setIsFirstPage(postPage.isIsFirstPage());
        trendVoPage.setIsLastPage(postPage.isIsLastPage());
        trendVoPage.setList(trendVoList);
        trendVoPage.setTotal(total);
        return trendVoPage;
    }

    @Override
    public PageInfo<FollowVo> searchUser(long page, long limit, String keyword, String uid) {
        List<FollowVo> list = new ArrayList<>();

        //得到所有搜索的用户
        List<User> userList = userMapper.getUserLikeByKeyword(keyword);
        //得到当前用户所有关注的用户
        List<Follow> followList = followMapper.getPageByUid(null,null,Long.valueOf(uid));
        //所有关注者
        List<Long> ids = followList.stream().map(Follow::getFid).toList();

        FollowVo followVo;
        for (User user : userList) {
            followVo = new FollowVo();
            followVo.setIsfollow(ids.contains(user.getUserId()))
                    .setUid(user.getUserId())
                    .setUsername(user.getUsername())
                    .setAvatar(user.getAvatar())
                    .setFanCount(user.getFanCount())
                    .setUserId(user.getUserId());
            list.add(followVo);
        }
        return PageUtils.getPages((int) page, (int) limit, list);
    }

    @Override
    public User updateUser(User user) {
        userMapper.updateById(user);
        return user;
    }

    @Override
    public User getById(Long id) {
        return userMapper.getUserByUserId(id);
    }

    @Override
    public List<UserVo> searchUserByUsername(String username) {
        List<User> userList = userMapper.getUserByUsername(username);
        if (userList.isEmpty()) {
            return new ArrayList<>();
        }
        return ConvertUtils.sourceToTarget(userList, UserVo.class);
    }

    @Override
    public UserRecordVo getUserRecord(String uid) {
        String userRecordKey = PlatformConstant.USER_RECORD + uid;
        UserRecordVo userRecordVo = new UserRecordVo();
        if (Boolean.TRUE.equals(redisUtils.hasKey(userRecordKey))) {
            userRecordVo = JsonUtils.parseObject(redisUtils.get(userRecordKey), UserRecordVo.class);
        }
        return userRecordVo;
    }

    @Override
    public void clearUserRecord(String uid, Integer type) {
        String userRecordKey = PlatformConstant.USER_RECORD + uid;
        UserRecordVo userRecordVo;
        if (Boolean.TRUE.equals(redisUtils.hasKey(userRecordKey))) {
            userRecordVo = JsonUtils.parseObject(redisUtils.get(userRecordKey), UserRecordVo.class);
            if (type == 1) {
                userRecordVo.setAgreeCollectionCount(0L);
            } else if (type == 2) {
                userRecordVo.setAddFollowCount(0L);
            } else {
                userRecordVo.setNoreplyCount(0L);
            }
            redisUtils.set(userRecordKey, JsonUtils.toJsonString(userRecordVo));
        }
    }

    @Override
    public List<String> getAllSearchRecord(String uid) {
        String userRecordKey = PlatformConstant.USER_SEARCH_RECORD + uid;
        return redisUtils.lRange(userRecordKey, 0, 20);
    }

    @Override
    public void addSearchRecord(SearchRecordDTO searchRecordDTO) {
        String userSearchRecordKey = PlatformConstant.USER_SEARCH_RECORD + searchRecordDTO.getUid();
        if (Boolean.TRUE.equals(redisUtils.hasKey(userSearchRecordKey))) {
            redisUtils.lRemove(userSearchRecordKey, 0, searchRecordDTO.getKeyword());
        }
        redisUtils.lLeftPush(userSearchRecordKey, searchRecordDTO.getKeyword());
    }

    @Override
    public void deleteSearchRecord(List<String> words, String uid) {
        String userSearchRecordKey = PlatformConstant.USER_SEARCH_RECORD + uid;
        if (Boolean.TRUE.equals(redisUtils.hasKey(userSearchRecordKey))) {
            for (String word : words) {
                redisUtils.lRemove(userSearchRecordKey, 0, word);
            }
        }
    }
}
